package com.bwie.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.exception.BusinessException;
import com.bwie.common.pojo.dto.HouseDto;
import com.bwie.common.pojo.po.CardPo;
import com.bwie.common.pojo.po.HousePo;
import com.bwie.common.pojo.po.UserPo;
import com.bwie.common.result.PageResult;
import com.bwie.common.result.Result;
import com.bwie.common.utils.JwtUtils;
import com.bwie.mapper.HouseMapper;
import com.bwie.pojo.HousePoEs;
import com.bwie.service.HouseService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.catalina.User;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static java.math.BigDecimal.*;

@Service
public class HouseServiceImpl implements HouseService {
    @Autowired
    private HouseMapper houseMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public Result getHouseList(HouseDto houseDto) {
        PageHelper.startPage(houseDto.getPageNum(),houseDto.getPageSize());
        List<HousePo> list = houseMapper.getHouseList(houseDto);
        for (HousePo housePo : list) {
            BigDecimal sum = housePo.getHouseArea().multiply(housePo.getHousePrice()).multiply(new BigDecimal(0.97));
            housePo.setMyPrice(sum);
        }
        PageInfo<HousePo> housePoPageInfo = new PageInfo<>(list);
        return PageResult.toResult(housePoPageInfo.getTotal(),housePoPageInfo.getList());
    }

    @Override
    public List<HousePo> getHouseListSynchronousEs(HouseDto houseDto) {
        List<HousePo> list = houseMapper.getHouseList(houseDto);
        return list;
    }
    @Autowired
    private KafkaTemplate<String,Object> kafkaTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result houseBooking(HouseDto houseDto) {
        if(ObjectUtil.isEmpty(houseDto)){
            throw new BusinessException(Result.error("参数有误"));
        }
        if(houseDto.getIsBooking()==1){
            throw new BusinessException(Result.error("已经被预购了"));
        }
        //防止多次点击
        Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent("bookBing:ifabsent" + houseDto.getHouseId(),
                1, 30,TimeUnit.MINUTES);
        if(!ifAbsent){
            throw new BusinessException(Result.error("请检查是否已经预约"));
        }
        //获取用户信息
        UserPo userPo = getUserMsg();

        //修改预约状态
        houseMapper.updateIsBooking(houseDto.getHouseId(),houseDto.getIsBooking());
        //添加我的预约
        houseMapper.addUserBooking(userPo.getUserId(),houseDto.getHouseId());
        //异步发送短信
        kafkaTemplate.send("sendMsg", userPo.getPhone());

        redisTemplate.delete("bookBing:ifabsent" + houseDto.getHouseId());

        return Result.success(null,"预约成功");
    }

    /**
     *回显房屋信息
     * @param houseId
     * @return
     */
    @Override
    public Result getHouseByHouseId(Integer houseId) {
        HousePo housePo = houseMapper.getHouseByHouseId(houseId);
        return Result.success(housePo);
    }

    /**
     * 查询用户银行卡信息
     * @return
     */
    @Override
    public Result ByUserIdSelectCardMsg() {
        UserPo userMsg = getUserMsg();
        List<CardPo> list = houseMapper.ByUserIdSelectCardMsg(userMsg.getUserId());
        return Result.success(list);
    }

    @Override
    public Result buyHouse(HouseDto houseDto) {
        UserPo userPo = getUserMsg();
        //计算租金
        BigDecimal userSumPrice = houseDto.getHouseArea().multiply(houseDto.getHousePrice()).multiply(new BigDecimal(0.95));
        //查询用户银行卡余额
        BigDecimal cardSumMoney = houseMapper.getCardSumMoney(userPo.getUserId(),houseDto.getCardId());
        if(cardSumMoney.compareTo(userSumPrice)< 0){
            throw new BusinessException(Result.error("余额不足 请充值"));
        }
        //扣除余额
        houseMapper.subUserIdBalance(userPo.getUserId(),houseDto.getCardId(),userSumPrice);
        return null;
    }

    /**
     * 获取用户信息
     * @return
     */
    private UserPo getUserMsg() {
        String header = request.getHeader(TokenConstants.TOKEN);
        String userKey = JwtUtils.getUserKey(header);
        UserPo user = (UserPo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        return user;
    }
}
